#include "register_dialog.h"
#include "ui_register_dialog.h"
#include "global.h"
#include <QDebug>
#include <QRegularExpression>
#include "httpmgr.h"
#include "configmgr.h"


Register_Dialog::Register_Dialog(QWidget *parent) :
    QDialog(parent),rsacrypt_(new RsaCrypt()),
    ui(new Ui::Register_Dialog)
{
    ui->setupUi(this);

    //设置默认输入方式为PassWord模式
    ui->pass_edit->setEchoMode(QLineEdit::EchoMode::Password);
    ui->confirm_edit->setEchoMode(QLineEdit::EchoMode::Password);
    ui->err_tip->setProperty("state","normal");
    repolish(ui->err_tip);
    ui->err_tip->clear();
    initHandlers();//初始化回调容器

    //外部信号
    connect(HttpMgr::getInstance().get(),&HttpMgr::sig_reg_mod_finish,this,&Register_Dialog::slot_reg_mod_finish);

    //自身控件
    connect(ui->get_code_btn,&QPushButton::clicked,this,&Register_Dialog::SlotGetCode);//获取验证码
    connect(ui->register_btn,&QPushButton::clicked,this,&Register_Dialog::SlotRegister);//开始注册
    connect(ui->cancel_btn,&QPushButton::clicked,this,&Register_Dialog::switchLogin);//取消注册

    connect(ui->pass_visi_label,&Visiablelabel::clicked,this,&Register_Dialog::SlotPassVisiable);//密码文本是否可见
    connect(ui->confirm_visi_label,&Visiablelabel::clicked,this,&Register_Dialog::SlotConfirmVisiable);//确认密码文本是否可见

    //检查输入是否合理
    connect(ui->user_edit,&QLineEdit::editingFinished,this,[this](){
        checkUserValid();
    });
    connect(ui->email_edit, &QLineEdit::editingFinished, this, [this](){
        checkEmailValid();
    });
    connect(ui->pass_edit, &QLineEdit::editingFinished, this, [this](){
        checkPassValid();
    });
    connect(ui->confirm_edit, &QLineEdit::editingFinished, this, [this](){
        checkConfirmValid();
    });
    connect(ui->verify_edit, &QLineEdit::editingFinished, this, [this](){
            checkVarifyValid();
    });
    //connect()
}

Register_Dialog::~Register_Dialog()
{
    delete rsacrypt_;
    delete ui;
}

void Register_Dialog::AddTipErr(TipErr te, QString tips)
{
    _tip_errs[te] = tips;
    showTip(tips, false);
}
void Register_Dialog::DelTipErr(TipErr te)
{
    _tip_errs.remove(te);
    if(_tip_errs.empty()){
      ui->err_tip->clear();
      return;
    }
    showTip(_tip_errs.first(), false);
}

void Register_Dialog::initHandlers()
{
    //注册获取验证码回包逻辑
    _handlers.insert(ReqId::ID_GET_VARIFY_CODE, [this](QJsonObject jsonObj){
        int error = jsonObj["error"].toInt();
        if(error != ErrorCodes::SUCCESS){
            showTip(tr("参数错误"),false);
            return;
        }
        auto email = jsonObj["email"].toString();
        showTip(tr("验证码已发送到邮箱，注意查收"), true);
        qDebug()<< "email is " << email ;
    });

    _handlers.insert(ReqId::ID_REG_USER, [this](QJsonObject jsonObj){
           int error = jsonObj["error"].toInt();
           if(error == ErrorCodes::VarifyExpired){
               showTip(tr("验证码已过期"),false);
               return;
           }
           else if(error == ErrorCodes::VarifyCodeErr)
           {
               showTip(tr("验证码错误"),false);
               return;
           }
           else if(error == ErrorCodes::UserExist)
           {
               showTip(tr("用户或邮箱已存在"),false);
               return;
           }
           //showTip(tr("用户注册成功"), true);
            emit switchRegSuccess();
       });
}

void Register_Dialog::SlotGetCode()
{
    //获取edit文本内容
    QString email = ui->email_edit->text();
    qDebug() << " 输入的email:"<< email;

    // 使用正则表达式验证电子邮件格式
    QRegularExpression emailRegex(R"(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))");
    QRegularExpressionMatch match = emailRegex.match(email);

    if (match.hasMatch()) {
        //发送http请求获取验证码
        QJsonObject json_obj;
        json_obj["email"] = email;

        QString port = ConfigMgr::getInstance()->getGateServerPort();
        QString ip = ConfigMgr::getInstance()->getGateServerIp();
        QString post = ConfigMgr::getInstance()->getPostGetVerifyCode();
        QString url = "http://" + ip + ":" + port + post;

        HttpMgr::getInstance()->PostHttpReq(QUrl(url),
                     json_obj, ReqId::ID_GET_VARIFY_CODE,Modules::REGISTERMOD);
    } else {

       qDebug() << "电子邮件格式不正确";

       //关于tr:Qt会查找与当前用户界面语言相匹配的翻译文件，
       //并尝试从中找到这个字符串的对应翻译。如果找到了翻译，它会返回翻译后的字符串；
       //如果没有找到，它会默认返回原始字符串。
       showTip(tr("电子邮件格式不正确"),false);
    }
}

void Register_Dialog::SlotRegister()
{
    bool valid = checkUserValid();
    if(!valid){
        return;
    }
    valid = checkEmailValid();
    if(!valid){
        return;
    }
    valid = checkPassValid();
    if(!valid){
        return;
    }
    valid = checkConfirmValid();
    if(!valid){
        return;
    }
    valid = checkVarifyValid();
    if(!valid){
        return;
    }

    //发送http请求注册用户
    QJsonObject json_obj;
    json_obj["user"] = ui->user_edit->text();
    json_obj["email"] = ui->email_edit->text();
    QString password = ui->pass_edit->text();
    qDebug() << "原始密码：" << password;
    QString crypt_pass =  rsacrypt_->rsa_pri_encrypt_base64(password);
    qDebug() << "加密密码" << crypt_pass;
    json_obj["passwd"] = crypt_pass;
    json_obj["confirm"] = crypt_pass;
    json_obj["varifycode"] = ui->verify_edit->text();

    crypt_pass =  rsacrypt_->rsa_pub_decrypt_base64(crypt_pass);
    qDebug() << "解密密码" << crypt_pass;

    QString port = ConfigMgr::getInstance()->getGateServerPort();
    QString ip = ConfigMgr::getInstance()->getGateServerIp();
    QString post = ConfigMgr::getInstance()->getPostUserRegister();
    QString url = "http://" + ip + ":" + port + post;
    qDebug() << url;
    HttpMgr::getInstance()->PostHttpReq(QUrl(url),
                 json_obj, ReqId::ID_REG_USER,Modules::REGISTERMOD);

}

void Register_Dialog::SlotPassVisiable(Visiablelabel::LabelState state)
{
    if(state == Visiablelabel::LabelState::Visiable)
    {
        ui->pass_edit->setEchoMode(QLineEdit::EchoMode::Password);
    }
    else
    {
        ui->pass_edit->setEchoMode(QLineEdit::EchoMode::Normal);
    }
}

void Register_Dialog::SlotConfirmVisiable(Visiablelabel::LabelState state)
{
    if(state == Visiablelabel::LabelState::Visiable)
    {
        ui->confirm_edit->setEchoMode(QLineEdit::EchoMode::Password);
    }
    else
    {
        ui->confirm_edit->setEchoMode(QLineEdit::EchoMode::Normal);
    }
}

bool Register_Dialog::checkUserValid()
{
    if(ui->user_edit->text() == ""){
        AddTipErr(TipErr::TIP_USER_ERR, tr("用户名不能为空"));
        return false;
    }
    DelTipErr(TipErr::TIP_USER_ERR);
    return true;
}
bool Register_Dialog::checkPassValid()
{
    auto pass = ui->pass_edit->text();
    if(pass.length() < 6 || pass.length()>15){
        //提示长度不准确
        AddTipErr(TipErr::TIP_PWD_ERR, tr("密码长度应为6~15"));
        return false;
    }
    // 创建一个正则表达式对象，按照上述密码要求
    // 这个正则表达式解释：
    // ^[a-zA-Z0-9!@#$%^&*]{6,15}$ 密码长度至少6，可以是字母、数字和特定的特殊字符
    QRegularExpression regExp("^[a-zA-Z0-9!@#$%^&*]{6,15}$");
    bool match = regExp.match(pass).hasMatch();
    if(!match){
        //提示字符非法
        AddTipErr(TipErr::TIP_PWD_ERR, tr("不能包含非法字符"));
        return false;;
    }
    DelTipErr(TipErr::TIP_PWD_ERR);
    return true;
}

bool Register_Dialog::checkConfirmValid()
{
    QString str1 = ui->pass_edit->text();
    QString str2 = ui->confirm_edit->text();
    if(str1 == str2)
    {
        DelTipErr(TipErr::TIP_PWD_CONFIRM);
        return true;
    }
    AddTipErr(TipErr::TIP_PWD_CONFIRM, tr("确认密码不一致"));
    return false;
}
bool Register_Dialog::checkEmailValid()
{
    //验证邮箱的地址正则表达式
    auto email = ui->email_edit->text();
    // 邮箱地址的正则表达式
    QRegularExpression regex(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+)");
    bool match = regex.match(email).hasMatch(); // 执行正则表达式匹配
    if(!match){
        //提示邮箱不正确
        AddTipErr(TipErr::TIP_EMAIL_ERR, tr("邮箱地址格式不正确"));
        return false;
    }
    DelTipErr(TipErr::TIP_EMAIL_ERR);
    return true;
}
bool Register_Dialog::checkVarifyValid()
{
    auto pass = ui->verify_edit->text();
    if(pass.isEmpty()){
        AddTipErr(TipErr::TIP_VARIFY_ERR, tr("验证码不能为空"));
        return false;
    }
    DelTipErr(TipErr::TIP_VARIFY_ERR);
    return true;
}

void Register_Dialog::slot_reg_mod_finish(ReqId id, QString str, ErrorCodes er)
{
    if(er != ErrorCodes::SUCCESS){
        showTip(tr("网络请求错误"),false);
        return;
    }
    // 解析 JSON 字符串,res需转化为QByteArray
    QJsonDocument jsonDoc = QJsonDocument::fromJson(str.toUtf8());
    //json解析错误
    if(jsonDoc.isNull()){
        showTip(tr("json解析错误"),false);
        return;
    }
    //json解析错误
    if(!jsonDoc.isObject()){
        showTip(tr("json解析错误"),false);
        return;
    }
    QJsonObject jsonObj = jsonDoc.object();

    //调用对应的逻辑
    _handlers[id](jsonObj);

    return;
}

void Register_Dialog::showTip(QString str,bool is_ok)
{
    if(is_ok)
    {
        ui->err_tip->setProperty("state","normal");
    }
     else
    {
        ui->err_tip->setProperty("state","error");
    }
    ui->err_tip->clear();
    ui->err_tip->setText(str);

    repolish(ui->err_tip);
}

